﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using CamlexNET;
using Microsoft.SharePoint;
using TennisSite.Controls;
using TennisSite.FeatureReceivers;
using TennisSite.Tools;
using System.Web;

namespace TennisSite.WebParts
{
    public class PlayersWebPart : WebPart
    {
        private const string _customControlPath = @"~/_CONTROLTEMPLATES/TennisSite/PlayersCustControl.ascx";
        private const string _mainFieldsQuery = "<FieldRef Name=\"FullName\" /><FieldRef Name=\"Gender\" /><FieldRef Name=\"User\" /><FieldRef Name=\"Country\" />";
        private const string _operationFailedMessage = "Sorry, something went wrong. Contact site administrator for details.";

        private PlayersCustControl _custControl;

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            CreateControls();

            SPList playersList = SPContext.Current.List;

            FillSortingFields();
        }
        
        protected void CreateControls()
        {
            try
            {
                _custControl = (PlayersCustControl)Page.LoadControl(_customControlPath);

                _custControl.SortButton.Click += new EventHandler(SortButton_Click);
                _custControl.ExportButton.Click += new EventHandler(ExportButton_Click);
                _custControl.ImportButton.Click += new EventHandler(ImportButton_Click);

                this.Controls.Add(_custControl);
            }
            catch (Exception e)
            {
                throw new SPException(_operationFailedMessage);
            }
        }

        private void ExportButton_Click(object sender, EventArgs eventArgs)
        {
            try
            {
                SPList list = SPContext.Current.List;
                SPQuery mainFieldsQuery = new SPQuery();
                mainFieldsQuery.ViewFields = _mainFieldsQuery;

                DataTable table = list.GetItems(mainFieldsQuery).GetDataTable();

                if (table != null)
                {
                    byte[] templateBuffer = GetTemplateBuffer();
                    ExcelHelper.ExportToExcel(table, templateBuffer);
                }
                //HttpContext.Current.Response.Redirect(HttpContext.Current.Request.Url.ToString());
                throw new Exception();
            }
            catch(Exception e)
            {
                throw new SPException(_operationFailedMessage);
            }
        }

        private byte[] GetTemplateBuffer()
        {
            SPWeb web = SPContext.Current.Web;

            SPFile file = web.GetFile("template.xls");
            byte[] buffer = file.OpenBinary();

            return buffer;
        }

        private void ImportButton_Click(object sender, EventArgs eventArgs)
        {
            if (_custControl.FileUpload.HasFile)
            {
                try
                {
                    string filePath = Path.Combine(Path.GetTempPath(), _custControl.FileUpload.FileName);
                    _custControl.FileUpload.PostedFile.SaveAs(filePath);

                    List<DataTable> tables = ExcelHelper.GetValidTables(filePath, PlayersListInfo.RequiredColumns);

                    if (tables.Count > 0)
                    {
                        InsertItemsIntoList(tables);
                    }
                }
                catch (Exception e)
                {
                    throw new SPException(_operationFailedMessage);
                }
            }
        }

        private void InsertItemsIntoList(List<DataTable> tables)
        {
            SPWeb web = SPContext.Current.Web;
            SPList playersList = SPContext.Current.List;

            List<PlayersListInfo> listInfos = GetImportedItems(tables);

            foreach (PlayersListInfo listInfo in listInfos)
            {
                SPListItem listItem = playersList.Items.Add();
                listItem[PlayersListInfo.FullNameFieldName] = listInfo.FullName;
                listItem[PlayersListInfo.GenderFieldName] = listInfo.Gender;

                if (web.SiteUsers.Cast<SPUser>().Any(e => e.LoginName.ToLower() == listInfo.User.ToLower()))
                {
                    listItem[PlayersListInfo.UserFieldName] = web.SiteUsers[listInfo.User];
                }
                else
                {
                    throw new SPException(string.Format("Import failed. User '{0}' not found on site", listInfo.User));
                }

                SPList countriesList = web.GetList(web.Url + TennisSiteFeatureReceiver.COUNTRIES_LIST_URL);
                SPListItem country = countriesList.Items.Cast<SPListItem>().Single(e => e["Country"].ToString().ToLower() == listInfo.Country.ToLower());
                int index = country.ID;

                listItem[PlayersListInfo.CountryFieldName] = new SPFieldLookupValue(index, "");

                listItem.Update();
            }
        }

        private List<PlayersListInfo> GetImportedItems(List<DataTable> tables)
        {
            List<PlayersListInfo> items = new List<PlayersListInfo>();

            foreach (DataTable table in tables)
            {
                foreach (DataRow row in table.Rows)
                {
                    PlayersListInfo info = new PlayersListInfo();
                    info.FullName = row[PlayersListInfo.FullNameFieldName].ToString();
                    info.Gender = row[PlayersListInfo.GenderFieldName].ToString();
                    info.User = row[PlayersListInfo.UserFieldName].ToString();
                    info.Country = row[PlayersListInfo.CountryFieldName].ToString();

                    items.Add(info);
                }
            }

            return items;
        }

        private void SortButton_Click(object sender, EventArgs args)
        {
            if (_custControl.SortFieldsDropDown.Items.Count > 0)
            {
                SPList playersList = SPContext.Current.List;

                SortListByField(playersList, _custControl.SortFieldsDropDown.SelectedValue, SortDirection.Ascending);
            }
        }

        private void SortListByField(SPList list, string fieldName, SortDirection sortDirection)
        {
            string query = Camlex.Query().OrderBy(e => e[fieldName] as Camlex.Asc).ToString();

            SPView mainView = list.DefaultView;
            mainView.Query = query;
            mainView.Update();
        }

        private void FillSortingFields()
        {
            if (_custControl.SortFieldsDropDown != null)
            {
                SPList list = SPContext.Current.List;

                List<string> sortingFields = new List<string>() { PlayersListInfo.CountryFieldName, PlayersListInfo.LinkFullNameFieldName };
                _custControl.SortFieldsDropDown.Items.Clear();

                foreach (string fieldName in sortingFields)
                {
                    if (list.Fields.Cast<SPField>().Any(e => e.InternalName == fieldName))
                    {
                        SPField field = list.Fields.Cast<SPField>().Single(e => e.InternalName == fieldName);
                        ListItem listItem = new ListItem(field.Title, field.InternalName);
                        _custControl.SortFieldsDropDown.Items.Add(listItem);
                    }
                }
            }
        }

        private void ShowJsMessage(string message)
        {
            this.Page.ClientScript.RegisterStartupScript(this.GetType(), "Warning", string.Format("<script language=JavaScript>alert('{0}');</script>", message));
        }
    }
}